From 0f53096b3db688220827c7ab2a86541428c16248 Mon Sep 17 00:00:00 2001 From: "cl349@freefall.cl.cam.ac.uk" Date: Mon, 2 Aug 2004 15:44:19 +0000 Subject: [PATCH] bitkeeper revision 1.1108.33.32 (410e6153m76cWDqwoNiwLL3JboItbA) fix zapping of pages mapped for/from other domains --- .../include/asm-xen/asm-i386/pgtable-2level.h | 34 +++++++++++++++++-- 1 file changed, 31 insertions(+), 3 deletions(-) diff --git a/linux-2.6.7-xen-sparse/include/asm-xen/asm-i386/pgtable-2level.h b/linux-2.6.7-xen-sparse/include/asm-xen/asm-i386/pgtable-2level.h index 65a53ef7d0..58e51fc2bd 100644 --- a/linux-2.6.7-xen-sparse/include/asm-xen/asm-i386/pgtable-2level.h +++ b/linux-2.6.7-xen-sparse/include/asm-xen/asm-i386/pgtable-2level.h @@ -75,10 +75,38 @@ static inline pte_t ptep_get_and_clear(pte_t *xp) } #define pte_same(a, b) ((a).pte_low == (b).pte_low) -#define pte_page(x) pfn_to_page(pte_pfn(x)) +/* + * We detect special mappings in one of two ways: + * 1. If the MFN is an I/O page then Xen will set the m2p entry + * to be outside our maximum possible pseudophys range. + * 2. If the MFN belongs to a different domain then we will certainly + * not have MFN in our p2m table. Conversely, if the page is ours, + * then we'll have p2m(m2p(MFN))==MFN. + * If we detect a special mapping then it doesn't have a 'struct page'. + * We force !VALID_PAGE() by returning an out-of-range pointer. + */ +#define pte_page(_pte) \ +({ \ + unsigned long mfn = (_pte).pte_low >> PAGE_SHIFT; \ + unsigned long pfn = mfn_to_pfn(mfn); \ + if ( (pfn >= max_mapnr) || (pfn_to_mfn(pfn) != mfn) ) \ + pfn = max_mapnr; /* special: force !VALID_PAGE() */ \ + pfn_to_page(pfn); \ +}) + #define pte_none(x) (!(x).pte_low) -/* XXXcl check valid because msync.c:filemap_sync_pte calls without pte_present check */ -#define pte_pfn(x) ((unsigned long)((((x).pte_low & 1 ? machine_to_phys((x).pte_low) : (x).pte_low) >> PAGE_SHIFT))) +/* See comments above pte_page */ +/* XXXcl check pte_present because msync.c:filemap_sync_pte calls + * without pte_present check */ +#define pte_pfn(_pte) \ +({ \ + unsigned long mfn = (_pte).pte_low >> PAGE_SHIFT; \ + unsigned long pfn = pte_present(_pte) ? mfn_to_pfn(mfn) : mfn; \ + if ( (pfn >= max_mapnr) || (pfn_to_mfn(pfn) != mfn) ) \ + pfn = max_mapnr; /* special: force !pfn_valid() */ \ + pfn; \ +}) + #define pfn_pte(pfn, prot) __pte(((pfn) << PAGE_SHIFT) | pgprot_val(prot)) #define pfn_pte_ma(pfn, prot) __pte_ma(((pfn) << PAGE_SHIFT) | pgprot_val(prot)) #define pfn_pmd(pfn, prot) __pmd(((pfn) << PAGE_SHIFT) | pgprot_val(prot)) -- 2.30.2